package com.spbl.apache.shiro.config;

import com.spbl.common.exception.BusinessException;
import com.spbl.entity.SysUser;
import com.spbl.service.SysUserService;
import com.spbl.vo.SysUserMenuPermissonVo;
import com.spbl.vo.SysUserRoleVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Description(自定义realm 权限验证)
 * author: Gao xueyong
 * Create at: 2020/6/7 6:35 下午
 */
@Slf4j
@Component
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService sysUserService;

    /**
     * 授权
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simInfo = new SimpleAuthorizationInfo();
        String userAccount = (String) principalCollection.getPrimaryPrincipal();
        SysUser sysUser = sysUserService.getSysUserByLoginName(userAccount);
        if (null == sysUser) {
            log.error("获取授权失败！用户信息为null,userAccount={}", userAccount);
            throw new BusinessException("获取授权失败！用户信息为null,userAccount=" + userAccount);
        }
        List<SysUserRoleVo> userRoles = sysUserService.getUserRoleInfoByUserId(sysUser.getId());
        Set<String> roles = userRoles.stream().map(x -> x.getEnname()).collect(Collectors.toSet());
        simInfo.setRoles(roles);
        List<SysUserMenuPermissonVo> userPerMission = sysUserService.getUserMenuPermissionInfoByUserId(sysUser.getId());
        Set<String> permission = userPerMission.stream().map(x -> x.getPermission()).collect(Collectors.toSet());
        simInfo.setStringPermissions(permission);
        return simInfo;
    }

    /**
     * 登录验证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        long start = System.currentTimeMillis();
        Object principal = authenticationToken.getPrincipal();
        if (null == principal) {
            log.error("未登录，请登录！");
            //抛异常t
            throw new BusinessException("未登录，请登录！");
        }
        String userCode = principal.toString();
        SysUser sysUser = sysUserService.getSysUserByLoginName(userCode);
        if (null == sysUser) {
            log.error("账号错误！");
            // 抛异常
            throw new BusinessException("账号错误！请重写输入！");
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, sysUser.getPassword(),
                ByteSource.Util.bytes(sysUser.getLoginName()), this.getClass().getName());
        log.debug("登录验证耗时:{}",System.currentTimeMillis() - start);
        return simpleAuthenticationInfo;
    }
}
